package org.lemon.db.store.fs;

import java.io.File;
import java.nio.file.OpenOption;
import java.nio.file.StandardOpenOption;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Set;

/**
 * This utility class contains utility functions that use the file system
 * abstraction
 * @since 2024-12-07 16:44
 */
public class FileUtils {

    /**
     * {@link StandardOpenOption#READ}.
     */
    public static final Set<? extends OpenOption> R = Collections.singleton(StandardOpenOption.READ);

    /**
     * {@link StandardOpenOption#READ}, {@link StandardOpenOption#WRITE}, and
     * {@link StandardOpenOption#CREATE}.
     */
    public static final Set<? extends OpenOption> RW = Collections
        .unmodifiableSet(EnumSet.of(StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE));

    /**
     * {@link StandardOpenOption#READ}, {@link StandardOpenOption#WRITE},
     * {@link StandardOpenOption#CREATE}, and {@link StandardOpenOption#SYNC}.
     */
    public static final Set<? extends OpenOption> RWS = Collections.unmodifiableSet(EnumSet.of(StandardOpenOption.READ,
        StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.SYNC));

    /**
     * {@link StandardOpenOption#READ}, {@link StandardOpenOption#WRITE},
     * {@link StandardOpenOption#CREATE}, and {@link StandardOpenOption#DSYNC}.
     */
    public static final Set<? extends OpenOption> RWD = Collections.unmodifiableSet(EnumSet.of(StandardOpenOption.READ,
        StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.DSYNC));

    /**
     * Checks if a file exists.
     *
     * @param fileName the file name
     * @return true if it exists
     */
    public static boolean exists(String fileName) {
        return new File(fileName).exists();
    }

    public static boolean canWrite(String fileName) {
        return new File(fileName).canWrite();
    }

    /**
     * Check if it is a file or a directory.
     * <code>java.nio.file.attribute.Attributes.
     * readBasicFileAttributes(file).isDirectory()</code>
     *
     * @param fileName the file or directory name
     * @return true if it is a directory
     */
    public static boolean isDirectory(String fileName) {
        return new File(fileName).isDirectory();
    }

    /**
     * Convert the string representation to a set.
     *
     * @param mode the mode as a string
     * @return the set
     */
    public static Set<? extends OpenOption> modeToOptions(String mode) {
        Set<? extends OpenOption> options;
        switch (mode) {
            case "r":
                options = R;
                break;
            case "rw":
                options = RW;
                break;
            case "rws":
                options = RWS;
                break;
            case "rwd":
                options = RWD;
                break;
            default:
                throw new IllegalArgumentException(mode);
        }
        return options;
    }


}
